﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PacketAnalyzer.Data
{
    public class PacketData : ICloneable
    {
        private System.Text.Encoding encoding = System.Text.Encoding.GetEncoding(51949);

        private int totalLength = 0;

        // 순서 유지용
        public List<string> keyList = new List<string>();

        public Dictionary<string, string> keyValuePair = new Dictionary<string, string>();

        public PacketData()
        {
        }

        public void Add(string key, string value)
        {
            // 중복 허용하지 말자

            //if (keyList.Contains(key))
            //{
            //    keyList.Remove(key);
            //}

            keyList.Add(key);

            //if (keyValuePair.ContainsKey(key))
            //{
            //    totalLength -= keyValuePair[key].Length;
            //    totalLength += value.Length;

            //    keyValuePair[key] = value;
            //    return;
            //}

            keyValuePair.Add(key, value);
            totalLength += value.Length;
        }

        public String Get(string key)
        {

            if (keyValuePair.ContainsKey(key))
                return keyValuePair[key];

            return null;
        }

        public void Clear()
        {
            // Initialize
            keyValuePair.Clear();
            keyList.Clear();
        }

        public int Length 
        {
            get { return totalLength; }
        }   

        public PacketData Merge(PacketData packetData)
        {
            foreach (string key in packetData.keyList)
            {
                keyList.Add(key);
            }

            foreach (KeyValuePair<string, string> kvp in packetData.keyValuePair)
            {
                keyValuePair.Add(kvp.Key, kvp.Value);
            }

            totalLength += packetData.Length;

            return this;
        }

        public static readonly int TYPE_NUMERIC = 0;
        public static readonly int TYPE_STRING = 1;
        
        // 패킷을 키+길이를 기준으로 자르고 dictionary 정보로 다시 매핑
        public int AddResult(string packet, string key, int packetType, int length, int pos, Dictionary<string, string> valueMap)
        {
            // 패킷 길이가 본래 정보보다 적을 경우
            if (packet.Length < pos + length)
            {
                // 이건 뭔가 이상하다..
                return pos;
            }

            //패킷에서 해당 Key Value를 추출
            byte[] result = encoding.GetBytes(packet);

            //string value = packet.Substring(pos, length);
            byte[] resultBytes = new byte[length];

            for (int i = pos; i < pos + length; i++)
            {
                resultBytes[i - pos] = result[i];
            }

            string value = encoding.GetString(resultBytes).Trim();

            if (valueMap != null && valueMap.ContainsKey(value))
            {
                value = valueMap[value] + " (" + value + ") ";
            }

            //Key값이 숫자일 경우 변환(double)
            if (packetType == TYPE_NUMERIC && !value.Equals(""))
            {
                double valueDouble = 1;

                if (value[0] == '-')
                {
                    valueDouble = -1;
                    value = value.Substring(1);
                }
                else if (value[0] == '+')
                {
                    value = value.Substring(1);
                }

                valueDouble *= double.Parse(value);

                value = valueDouble.ToString();
            }

            Add(key, value);

            return pos + length;
        }

        public int AddResult(string packet, string key, int length, int pos, Dictionary<string, string> valueMap)
        {
            if (packet.Length < pos + length)
            {
                // 이건 뭔가 이상하다..
                return pos;
            }

            byte[] result = encoding.GetBytes(packet);

            //string value = packet.Substring(pos, length);
            byte[] resultBytes = new byte[length];

            for (int i = pos; i < pos + length; i++)
            {
                resultBytes[i - pos] = result[i];
            }

            string value = encoding.GetString(resultBytes).Trim();

            if (valueMap != null && valueMap.ContainsKey(value))
                value = valueMap[value] + " (" + value + ")" ;

            Add(key, value);

            return pos + length;
        }

        public object Clone()
        {
            PacketData packetData = new PacketData();

            foreach (string key in keyList)
            {
                packetData.Add(key, keyValuePair[key]);
            }

            return packetData;
        }
    }
}
